//Wrapper for EE::Display
#pragma once
#include "stdafx.h"

namespace EsenthelNet
{
	///<summary>Aspect Ratio Mode, controls setting the sizes of screen coordinates - D.w and D.h</summary>
	public enum class AspectMode {
		///<summary>Sets D.h to 1.0, D.w will be proportional to D.h depending on the display aspect and selected resolution</summary>
		ASPECT_Y  , 
		///<summary>Sets D.w to 1.0, D.h will be proportional to D.w depending on the display aspect and selected resolution</summary>
		ASPECT_X  ,
	};
	///<summary>Bump Mapping Mode</summary>
	public enum class BumpMode {
		///<summary>Flat</summary>
		BUMP_FLAT    ,
		///<summary>Normal</summary>
		BUMP_NORMAL  , 
		///<summary>Rarallax</summary>
		BUMP_PARALLAX, 
		///<summary>Relief</summary>
		BUMP_RELIEF  
	};
	///<summary>Ambient Occlusion Mode</summary>
	public enum class AmbientMode {
		///<summary>Flat</summary>
		AMBIENT_FLAT ,
		///<summary>Low quality</summary>
		AMBIENT_LOW  ,
		///<summary>Medium quality</summary>
		AMBIENT_MED  , //
		///<summary>Hight quality</summary>
		AMBIENT_HIGH ,
		///<summary>Ultra quality</summary>
		AMBIENT_ULTRA
	};
	///<summary>Shadowing Mode</summary>
	public enum class ShadowMode {
		///<summary>None</summary>
		SHD_NONE   ,
		///<summary>Shadow mapping</summary>
		SHD_MAP    ,          
		///<summary>Hardware shadow mapping</summary>
		SHD_MAP_HW , 
		///<summary>Stencil shadows</summary>
		SHD_STENCIL
	};
	///<summary>Motion Blur Mode</summary>
	public enum class MotionMode {
		///<summary>None</summary>
		MOTION_NONE,
		///<summary>Scene is blurred according to camera velocities only, objects velocities are not taken into account</summary>
		MOTION_LOW , 
		///<summary>Scene is blurred according to camera and object velocities, available only in RT_DEFERRED renderer</summary>
		MOTION_HIGH 
	};
	///<summary>Depth of Field Mode</summary>
	public enum class DOFMode {
		///<summary>None</summary>
		DOF_NONE,
		///<summary>On</summary>
		DOF_ON  , 
		///<summary>High</summary>
		DOF_HIGH
	};
	///<summary>Edge Detect Mode</summary>
	public enum class EdgeDetectMode {
		///<summary>Disabled</summary>
		EDGE_DETECT_NONE,
		///<summary>Thin edges</summary>
		EDGE_DETECT_THIN,
		///<summary>Fat smoothed edges (slower)</summary>
		EDGE_DETECT_FAT
	};
	///<summary>Edge Softening Mode</summary>
	public enum class EdgeSoftenMode {
		///<summary>Disabled</summary>
		EDGE_SOFTEN_NONE,
		///<summary>Soften only those edges which are in front of the background, result is more sharp , but objects seem to be thinner</summary>
		EDGE_SOFTEN_NEAR, 
		///<summary>Soften both edges, result is more blurry, but objects aren't thinner</summary>
		EDGE_SOFTEN_BOTH 
	};
	///<summary>Information about using additional texture maps in material</summary>
	public enum class TextureUsage {
		///<summary>Map is always disabled</summary>
		TEX_USE_DISABLE,
		///<summary>Map is enabled for single materials only</summary>
		TEX_USE_SINGLE , 
		///<summary>Map is enabled for single materials and multiple materials which are blended together</summary>
		TEX_USE_MULTI 
	};
	///<summary>Field of View mode, determines calculating actual fov values</summary>
	public enum class FOVMode {
		///<summary>Vertical fov will be taken from given value, horizontal fov will be calculated proportionally </summary>
		FOV_Y , 
		///<summary>Horizontal fov will be taken from given value, vertical   fov will be calculated proportionally</summary>
		FOV_X ,
		///<summary>Both horizontal and vertical fov's will be taken from given value</summary>
		FOV_XY 
	};

	public enum class ShaderModel {
		///<summary>Unknown</summary>
		SM_UNKNOWN,
		///<summary>Model 2.0 (DirectX  9)</summary>
		SM_2, 
		///<summary>Model 3.0 (DirectX  9)</summary>
		SM_3,
		///<summary> Model 4.0 (DirectX 10)</summary>
		SM_4,
		///<summary>Model 4.1 (DirectX 10.1)</summary>
		SM_4_1,
		///<summary>Model 5.0 (DirectX 11)</summary>
		SM_5 
	};

	extern bool _lost();
	extern bool _reset();

	public ref class Display : DisplayDraw{
	internal:
		bool OnLost() {
			return true;
			//return Lost();
		}
		bool OnReset() {
			return true;
			//return Reset();
		}

		Display() {
			//D.lost = *static_cast<bool(*)()>(_lost);
			//D.reset = *static_cast<bool(*)()>(_reset);
		}

		static EsenthelNet::Display^ Instance;
	public:
		//event BooleanDelegate^ Lost;
		//event BooleanDelegate^ Reset;

		///<summary>Get Display Width (in pixels)</summary>
		PropMetGet(int, X, D.x)
		///<summary>Get Display Height (in pixels)</summary>
		PropMetGet(int, Y, D.y)
		///<summary>Get Display Width(in screen coordinates, usually something near 1.3, depends on selected resolution and aspect mode)</summary>
		PropMetGet(float, W, D.w)
		///<summary>Get Display Height (in screen coordinates, usually something near 1.0, depends on selected resolution and aspect mode)</summary>
		PropMetGet(float, H, D.h)
		///<summary>Get Display Frequency (refresh rate)</summary>
		PropMetGet(int, Freq, D.freq)
		///<summary>Get available shader model</summary>
		PropMetGet(ShaderModel, Shader_Model, D.shaderModel)
		///<summary>Get maximum available anisotropic filtering</summary>
		PropMetGet(int, MaxTexFilters, D.maxTexFilter)
		///<summary>Get number of fullscreen display modes</summary>
		PropMetGet(int, Modes, D.modes)
		///<summary>Get number of fullscreen display modes</summary>
		PropMetStringGet(DeviceDesc, D.deviceDesc)

		///<summary>Set Display Mode, -1=keep original value, if the method fails then previous mode is restored, if previous mode can't be restored then Exit is called</summary>
		EsenthelNet::Display^ Mode(float width, float height) { D.mode(width, height); return this; }
		///<summary>Set Display Mode, -1=keep original value, if the method fails then previous mode is restored, if previous mode can't be restored then Exit is called</summary>
		EsenthelNet::Display^ Mode(float width, float height, bool fullscreen) { D.mode(width, height, fullscreen); return this; }
		///<summary>Toggle Fullscreen/Windowed Mode, 'window_size'=if when switching to fullscreen want to set resolution from current window size instead of desktop size</summary>
		EsenthelNet::Display^ Toggle() { D.toggle(); return this; }
		///<summary>Toggle Fullscreen/Windowed Mode, 'window_size'=if when switching to fullscreen want to set resolution from current window size instead of desktop size</summary>
		EsenthelNet::Display^ Toggle(bool window_size) { D.toggle(window_size); return this; }

		///<summary>Get/Set Fullscreen Mode</summary>
		PropMet(bool, Fullscreen, D.full)
		///<summary>Get/Set Multi Sample Anti-Aliasing (0..Inf, default=0), enabling multi-sampling disables super-sampling and depth texture 'depthTexture', not supported in RT_DEFERRED renderer type</summary>
		PropMet(System::Byte, MultiSample, D.multiSample)
		///<summary>Get/set Super Sample Anti-Aliasing(0..5, default=0), enabling super-sampling disables multi-sampling</summary>
		PropMet(System::Byte, SuperSample, D.superSample)
		///<summary>Get/Set Aspect Mode (ASPECT_MODE, default=ASPECT_Y)</summary>
		PropMetTarget(AspectMode, Aspect_Mode, D.aspectMode, EE::ASPECT_MODE)
		///<summary>Get/Set Display Aspect Ratio 0=autodetect, 4/3, 5/4, 16/9, 16/10, default=0)</summary>
		PropMet(float, AspectDisplay, D.aspectDisplay)
		///<summary>set/get Bump Mapping Mode (BUMP_MODE, default=   BUMP_PARALLAX), using this method during application runtime requires setting 'D.set_shader' (please check comments on 'D.set_shader' for more info)</summary>
		PropMetTarget(BumpMode, Bump_Mode, D.bumpMode, EE::BUMP_MODE)
		///<summary>set/get Gamma value (-Inf..Inf, default=0)</summary>
		PropMet(float, Gamma, D.gamma)
		///<summary>set/get High Precision Render Targets (true/false, default=false)</summary>
		PropMet(bool, HpRt, D.hpRt)
		///<summary>set/get Color Dithering (true/false, default=true), this is used only when high precision render targets (hpRt) are enabled</summary>
		PropMet(bool, Dither, D.dither)
		///<summary>set/get Screen Synchronization (true/false, default=false)</summary>
		PropMet(bool, Sync, D.sync)
		///<summary>set/get Maximum Number of Lights (0=unlimited, 1..255, default=0)</summary>
		PropMet(System::Byte, MaxLight, D.maxLight)
		///<summary>set/get Depth Texture (true/false, default=true), enabling depth texture usage increases performance of rendering and enables some effects in RT_SIMPLE and RT_FORWARD rendering, enabling depth texture disables multi-sampling, this option is available only on GeForce 6 and Radeon x1000 series or newer cards</summary>
		PropMet(bool, DepthTexture, D.depthTexture)
		///<summary>set/get Texture Filtering Quality (0..maxTexFilter(), default=8), 0=no filtering, 1=linear filtering, 2 and more=anisotropic filtering</summary>
		PropMet(System::Byte, TexFilter, D.texFilter)
		///<summary>set/get Texture Lod Level Quality(0..16, default=0), values bigger than zero indicate lower texture quality (smaller mip maps will be used), but faster rendering</summary>
		PropMet(System::Byte, TexLod, D.texLod)
		///<summary>set/get Macro Textures usage (true/false, default=true), determines usage of additional Macro Textures in Materials, using this method during application runtime requires setting 'D.set_shader' (please check comments on 'D.set_shader' for more info)</summary>
		PropMet(bool, TexMacro, D.texMacro)
		///<summary>set/get Detail Textures usage (TEXTURE_USAGE, default=   TEX_USE_MULTI), determines usage of additional Detail Textures in Materials, using this method during application runtime requires setting 'D.set_shader' (please check comments on 'D.set_shader' for more info)</summary>
		PropMetTarget(TextureUsage, TexDetail, D.texDetail, EE::TEXTURE_USAGE)
		///<summary>set/get Reflection Textures usage (TEXTURE_USAGE, default=   TEX_USE_MULTI), determines usage of additional Reflection Textures in Materials, using this method during application runtime requires setting 'D.set_shader' (please check comments on 'D.set_shader' for more info), currently reflection textures do not support 'TEX_USE_MULTI' mode</summary>
		PropMetTarget(TextureUsage, TexReflection, D.texReflection, EE::TEXTURE_USAGE)
		///<summary>set/get Leafs Bending animation (true/false, default=true), using this method during application runtime requires setting 'D.set_shader' (please check comments on 'D.set_shader' for more info)</summary>
		PropMet(bool, BendLeafs, D.bendLeafs)
		///<summary>set/get Particles Softing(true/false, default=true)</summary>
		PropMet(bool, SoftParticles, D.softParticles)
		///<summary>set/get Edge Detect Mode(EDGE_DETECT_MODE, default=EDGE_DETECT_NONE)</summary>
		PropMetTarget(EdgeDetectMode, EdgeDetect, D.edgeDetect, EE::EDGE_DETECT_MODE)

		///<summary>set/get HDR state(true/false, default=false), enables High Dynamic Lighting Range usage, enables automatic screen brightness adjustment (Tone Mapping)</summary>
		PropMet(bool, Hdr, D.hdr)
		///<summary>set/get HDR weighted luminance (true/false, default=true ), if true then uses (0.2125, 0.7154, 0.0721) weights for RGB components in luminance calculation, if false calculates luminance based on maximum of RGB components</summary>
		PropMet(bool, HdrWeighted, D.hdrWeighted)
		///<summary>set/get HDR exposure (0..Inf, default= 0.75), total scale of lighting</summary>
		PropMet(float, HdrExposure, D.hdrExposure)
		///<summary>set/get HDR contrast (0..Inf, default= 0.2 ), determines how much to darken bright scenes and how much to brighten dark scenes</summary>
		PropMet(float, HdrContrast, D.hdrContrast)
		///<summary>set/get HDR maximum darkening(0..hdrMaxBright, default= 0.1 )</summary>
		PropMet(float, HdrMaxDark, D.hdrMaxDark)
		///<summary>set/get HDR maximum brightening(hdrMaxDark..Inf, default= 2.0 )</summary>
		PropMet(float, HdrMaxBright, D.hdrMaxBright)
		///<summary>set/get HDR eye adaptation speed (1..Inf, default= 6.5 )</summary>
		PropMet(float, HdrSpeed, D.hdrSpeed)

		///<summary>set/get Bloom Original Color(0..Inf , default=1.0)</summary>
		PropMet(float, BloomOriginal, D.bloomOriginal)
		///<summary>set/get Bloom Scale (0..Inf , default=0.3)</summary>
		PropMet(float, BloomScale, D.bloomScale)
		///<summary>set/get Bloom Cutoff(0..Inf, default=0.3)</summary>
		PropMet(float, BloomCut, D.bloomCut)
		///<summary>set/get Bloom Overbright(true/false, default=false)</summary>
		PropMet(bool, BloomOverbright, D.bloomHalf)
		///<summary>set/get Bloom Half/Quarter (true/false, default=true ), this specifies wheter bloom should be calculated using half of quarter sized render targets (half is more precise but slower)</summary>
		PropMet(bool, BloomHalf, D.bloomHalf)
		///<summary>set/get Bloom Number of Blurs (1..4, default=2)</summary>
		PropMet(System::Byte, BloomBlurs, D.bloomBlurs)

		///<summary>set/get Ambient Mode (AMBIENT_MODE, default=AMBIENT_FLAT)</summary>
		PropMetTarget(AmbientMode, AmbMode, D.ambMode, EE::AMBIENT_MODE)
		///<summary>set/get Ambient Softing (0..3, default=1), if soften the AO result</summary>
		PropMet(System::Byte, AmbSoft, D.ambSoft)
		///<summary>set/get Ambient Jittering(true/false, default=true), jittering enables per pixel randomization of the AO samples</summary>
		PropMet(bool, AmbJitter, D.ambJitter)
		///<summary>set/get Ambient Normal Map Use (true/false, default=true), if include per pixel normal vectors from the render target</summary>
		PropMet(bool, AmbNormal, D.ambNormal)
		///<summary>set/get Ambient Half Resolution (true/false, default=true), if use half resolution buffers instead of the full sized buffers (when enabled gives approximately 4x performance improvement of AO effect)</summary>
		PropMet(bool, AmbHalfRes, D.ambHalfRes)
		///<summary>set/get Ambient Power(0..1, default= 0.4), this is equivalent to using ambColor with RGB components set to the same value</summary>
		PropMet(float, AmbPower, D.ambPower)
		///<summary>set/get Ambient Color(0..1 default=0.4)</summary>
		PropMetVecP(AmbColor, D.ambColor)
		///<summary>set/get Ambient Contrast(0..Inf, default=1.2)</summary>
		PropMet(float, AmbContrast, D.ambContrast)
		///<summary>set/get Ambient 2D Range(0..Inf, default=0.3)</summary>
		PropMet(float, AmbRange, D.ambRange)
		///<summary>set/get Ambient 3D Scale (0..Inf, default=2.5)</summary>
		PropMet(float, AmbScale, D.ambScale)
		///<summary>set/get Ambient Bias (0..1, default=0.3)</summary>
		PropMet(float, AmbBias, D.ambBias)

		///<summary>set/get Ambient Mode (AMBIENT_MODE, default=AMBIENT_FLAT)</summary>
		PropMetTarget(ShadowMode, ShdMode, D.shdMode, EE::SHADOW_MODE)
		///<summary>set/get Shadow Softing (0..2, default=0)</summary>
		PropMet(System::Byte, ShdSoft, D.shdSoft)
		///<summary>set/get Shadow Softing (0..2, default=0)</summary>
		PropMet(bool, ShdJitter, D.shdJitter)
		///<summary>set/get Shadow Flickering Decrease (true/false, default=false), this option reduces directional light shadow map flickering when rotating the camera, however at the expense of slightly increasing the shadow map blockiness, enable only when the flickering is really disturbing</summary>
		PropMet(bool, ShdReduceFlicker, D.shdReduceFlicker)
		///<summary>set/get Shadow Range Fraction(0.., default=1), this option can limit shadowing range to a fraction of the viewport range</summary>
		PropMet(float, ShdFrac, D.shdFrac)
		///<summary>set/get Shadow Fade  Fraction(0..1, default=1), this option specifies at which part of the shadowing range, shadow fading occurs</summary>
		PropMet(float, ShdFade, D.shdFade)
		///<summary>set/get Number of Shadow Maps (1..6, default=6), RT_FORWARD renderer supports only even numbers of maps</summary>
		PropMet(System::Byte, ShdMapSize, D.shdMapNum)
		///<summary>set/get Clouds Shadow Map Size(1..Inf, default=80)</summary>
		PropMet(int, CldMapSize, D.cldMapSize)

		///<summary>set/get Motion Blur Mode (MOTION_MODE, default=MOTION_NONE)</summary>
		PropMetTarget(MotionMode, MtnMode, D.mtnMode, EE::MOTION_MODE)
		///<summary>set/get Motion Blur Smooth Blurring (true/false , default=false), if set to true then 15 samples will be used when blurring, if false only 7 will be used</summary>
		PropMet(bool, MtnSmooth, D.mtnSmooth)
		///<summary>set/get Motion Blur Leaks  Removal(0..3, default=0), remove leaking of blurred background objects into not blurred foreground objects</summary>
		PropMet(System::Byte, MtnLeaks, D.mtnLeaks)
		///<summary>set/get Motion Blur Velocity Scale ( 0..Inf, default=0.04)</summary>
		PropMet(float, MtnScale, D.mtnScale)
		///<summary>set/get Motion Blur Correct Sky Velocity (true/false, default=true)</summary>
		PropMet(bool, MtnSkyVel, D.mtnSkyVel)

		///<summary>set/get Depth of Field Mode(DOF_MODE, default=DOF_NONE)</summary>
		PropMetTarget(DOFMode, DofMode, D.dofMode, EE::DOF_MODE)
		///<summary>set/get Depth of Field Half/Quarter (true/false, default= true)</summary>
		PropMet(bool, DofHalf, D.dofHalf)
		///<summary>set/get Depth of Field Number of Blurs (1..4, default=1)</summary>
		PropMet(System::Byte, DofBlurs, D.dofBlurs)
		///<summary>set/get Depth of Field Power(0..1, default=1)</summary>
		PropMet(float, DofPower, D.dofPower)
		///<summary>set/get Depth of Field Focus Position( 0..Inf, default= 0)</summary>
		PropMet(float, DofZ, D.dofZ)
		///<summary>set/get Depth of Field Focus Range (0..Inf , default=30)</summary>
		PropMet(float, DofRange, D.dofRange)

		///<summary>set Level of Detail factors</summary>
		EsenthelNet::Display^ Lod(float general, float shadow, float mirror) { D.lod(general, shadow, mirror); return this; }
		///<summary>set/get Level of Detail general factor which determines Lod selection, 0..Inf, default=1, it's a scaling factor: values from 0..1 increase details and values from 1..Inf decrease details</summary>
		PropMet(float, LodFactor, D.lodFactor)
		///<summary>set/get Level of Detail shadows factor which is also applied to shadows Lod selection, 0..Inf, defailt=2, it's a scaling factor: values from 0..1 increase details and values from 1..Inf decrease details</summary>
		PropMet(float, LodFactorShadow, D.lodFactorShadow)
		///<summary>set/get Level of Detail mirror  factor which is also applied to meshes rendered in mirrors Lod selection, 0..Inf, defailt=2, it's a scaling factor: values from 0..1 increase details and values from 1..Inf decrease details</summary>
		PropMet(float, LodFactorMirror, D.lodFactorMirror)

		///<summary>set/get Tesselation (true/false, default=true ), Tesselation smoothes the mesh polygons, it is available only on Shader Model>=5.0</summary>
		PropMet(bool, Tesselation, D.tesselation)
		///<summary>set/get Tesselation of Heightmaps (0..Inf, default=false)</summary>
		PropMet(bool, TesselationHeightmap, D.tesselationHeightmap)
		///<summary>set/get Tesselation Density (0..Inf, default=60)</summary>
		PropMet(float, TesselationDensity, D.tesselationDensity)

		///<summary>set/get Edge Softening Mode (EDGE_SOFTEN_MODE, default=EDGE_SOFTEN_NONE) (this is fake Anti-Aliasing, works best when combined with Super Sampling, it is not used when Multi Sampling is enabled)</summary>
		PropMetTarget(EdgeSoftenMode, Edge_Soften_Mode, D.edgeSoftenMode, EE::EDGE_SOFTEN_MODE)
		///<summary>set/get Edge Softening Power (0..1, default=1.0)</summary>
		PropMet(float, EdgeSoftenPower, D.edgeSoftenPower)

		///<summary>set/get Grass Range (0..Inf, default=50)</summary>
		PropMet(float, GrassRange, D.grassRange)
		///<summary>set/get Grass Shadow Casting (true/false, default=false)</summary>
		PropMet(bool, GrassShadow, D.grassShadow)
		///<summary>set/get Grass Drawing in Mirror (true/false, default=false)</summary>
		PropMet(bool, GrassMirror, D.grassMirror)

		///<summary>set/get Volumetric Lighting(true/false, default=false), supported only in Shadow Mapping mode and Shader Model>=3.0</summary>
		PropMet(bool, VolLight, D.volLight)
		///<summary>set/get Volumetric Mode(true/false, default=false), when true is set, Volumetric Light will be added to the scene, if false is set, Lerp to 1 will be performed</summary>
		PropMet(bool, VolAdd, D.volAdd)
		///<summary>set/get Volumetric Global Maximum (0..Inf , default=1.0)</summary>
		PropMet(float, VolMax, D.volMax)

		///<summary>set/get viewport near clip plane, default=0.05)</summary>
		PropMet(float, ViewFrom, D.viewFrom)
		///<summary>set/get viewport far  clip plane, default=100</summary>
		PropMet(float, ViewRange, D.viewRange)

		///<summary>force pixel aspect ratio to 1, this may be needed for rendering to textures for use later, default rendering should have this disabled, default=false</summary>
		EsenthelNet::Display^ ViewForceSquarePixel(bool squared) { D.viewForceSquarePixel(squared); return this; }

		//Methods:
		///<summary>clear screen and clear z buffer</summary>
		void Clear() { D.clear(); }
		///<summary>clear screen to 'color' and clear z buffer</summary>
		void Clear(EsenthelNet::Color^ color) { D.clear(*color->color); }
		///<summary>clear screen to 'color'</summary>
		void ClearCol(EsenthelNet::Color^ color) { D.clearCol(*color->color); }
		///<summary>clear screen to Black</summary>
		void ClearCol() { D.clearCol(); }
		///<summary>clear z buffer</summary>
		void ClearZ() { D.clearZ(); }

		PropMet(float, AmbientPower, D.ambPower)

	};
}